package org.example.database.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.database.DTO.ResumeDTO;
import org.example.database.Mapper.AdviceMapper;
import org.example.database.service.SiliconFlowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@Slf4j
public class SiliconFlowServiceImpl implements SiliconFlowService {

    @Value("${siliconflow.url}")
    private String apiUrl;

    @Value("${siliconflow.key}")
    private String apiKey;

    @Value("${siliconflow.model}")
    private String model;

    private final RestTemplate restTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private AdviceMapper adviceMapper;

    public SiliconFlowServiceImpl() {
        this.restTemplate = new RestTemplate();
    }

    /**
     * 从简历文本中提取结构化信息
     */
    @Override
    public ResumeDTO extractResumeInfo(String resumeText) {
        log.info("开始解析简历文本（使用SiliconFlow API）...");

        String prompt = String.format(""" 
            你是一个只返回 JSON 的工具。请确保输出是一个合法的 JSON 对象，中间没有任何多余的自然语言或注释说明。
            
            字段如下（如果无内容请用 null，简历评估结果先生成后插入,不为null）：
            - name（姓名）
            - major（专业）
            - educationBackground（学历背景）
            - academy（毕业院校）
            - workExperience（工作/实习经历）
            - skill（技能，数组）
            - jobIntention（求职意向）
            - certificate（证书，数组）
            - timeOfGraduation（毕业时间）
            - timeOfEnrollment（入学时间）
            - assessmentResult（简历评估结果）

            简历文本：
            %s

            仅返回 JSON 对象，请严格遵守格式：
            {
              "name": ...,
              ...
            }
            """, resumeText);

        Map<String, Object> message = new HashMap<>();
        message.put("role", "user");
        message.put("content", prompt);

        List<Map<String, Object>> messages = new ArrayList<>();
        messages.add(message);

        Map<String, Object> request = new HashMap<>();
        request.put("model", model);
        request.put("messages", messages);

        // 设置请求头
        org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
        headers.set("Authorization", "Bearer " + apiKey);
        headers.set("Content-Type", "application/json");

        org.springframework.http.HttpEntity<Map<String, Object>> entity = new org.springframework.http.HttpEntity<>(request, headers);

        Map<String, Object> response = restTemplate.postForObject(apiUrl, entity, Map.class);
        log.info("SiliconFlow API响应：{}", response);

        try {
            Map<String, Object> choices = ((List<Map<String, Object>>) response.get("choices")).get(0);
            Map<String, Object> messageResponse = (Map<String, Object>) choices.get("message");
            String content = (String) messageResponse.get("content");
            
            String jsonText = extractJsonBlock(content);
            log.info("提取的 JSON 内容为：{}", jsonText);
            return objectMapper.readValue(jsonText, ResumeDTO.class);
        } catch (Exception e) {
            log.error("解析SiliconFlow API响应失败", e);
            throw new RuntimeException("解析SiliconFlow API响应失败", e);
        }
    }

    /**
     * 从文本中提取第一个 JSON 块
     */
    private String extractJsonBlock(String text) {
        Pattern pattern = Pattern.compile("\\{(?:[^{}]|\\{[^{}]*\\})*\\}", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            return matcher.group();
        }
        throw new RuntimeException("未能从模型响应中提取出 JSON 内容");
    }

    /**
     * 匹配度计算
     */
    @Override
    public double calculateJobMatchScore(ResumeDTO resumeData, Map<String, Object> jobData) {
        String prompt = String.format("""
            请计算以下简历和职位之间的匹配度（0-1）。
            考虑因素包括：技能、教育背景、经验、职位要求等。

            简历数据：
            %s

            职位数据：
            %s

            仅返回0到1之间的匹配度分数。
            """, resumeData.toString(), jobData.toString());

        Map<String, Object> message = new HashMap<>();
        message.put("role", "user");
        message.put("content", prompt);

        List<Map<String, Object>> messages = new ArrayList<>();
        messages.add(message);

        Map<String, Object> request = new HashMap<>();
        request.put("model", model);
        request.put("messages", messages);

        // 设置请求头
        org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
        headers.set("Authorization", "Bearer " + apiKey);
        headers.set("Content-Type", "application/json");

        org.springframework.http.HttpEntity<Map<String, Object>> entity = new org.springframework.http.HttpEntity<>(request, headers);

        Map<String, Object> response = restTemplate.postForObject(apiUrl, entity, Map.class);

        try {
            Map<String, Object> choices = ((List<Map<String, Object>>) response.get("choices")).get(0);
            Map<String, Object> messageResponse = (Map<String, Object>) choices.get("message");
            String content = (String) messageResponse.get("content");
            
            return Double.parseDouble(content.trim());
        } catch (Exception e) {
            log.error("解析SiliconFlow API响应失败", e);
            throw new RuntimeException("解析SiliconFlow API响应失败", e);
        }
    }
} 